#include "aerCustomEffect.hpp"


namespace aer {
 
CustomEffect::CustomEffect()
{
  m_input.pColor = NULL;
  m_input.pTime = NULL;
  
  /// Inputs
  addInput( "Color", m_input.pColor);
  addInput( "Time",  m_input.pTime);
  
  /// Outputs
  addOutput( "Color", m_output.color);
}

CustomEffect::~CustomEffect()
{
  m_program.release();
  m_renderTexture.release();
  
  m_output.color.release();
}
 
 
void CustomEffect::init()
{
  AER_CHECK( m_input.pColor != NULL );
  AER_CHECK( m_input.pTime != NULL );
  
  
  const char *fShader = AER_STRINGIFY(
    \x23 version 330\n
  
    in vec2 vTexCoord;    
    layout(location = 0) out vec4 fragColor;
  
    uniform sampler2D uSceneTex;
    uniform float uTime;
    
    void main()
    {
      fragColor = texture( uSceneTex, vTexCoord)*(0.5f*uTime);
    }
  );
  
  m_program.generate();
    m_program.addShaderSrc( Program::VERTEX_SHADER, ScreenQuad::GetVertexShader());
    m_program.addShaderSrc( Program::FRAGMENT_SHADER, fShader);
  AER_CHECK( m_program.link() );
  
  m_output.color.generate();
  m_output.color.bind();    
    m_output.color.setFilters( Texture::NEAREST, Texture::NEAREST);
    m_output.color.setWraps( Texture::CLAMP_TO_EDGE, Texture::CLAMP_TO_EDGE);
  m_output.color.unbind();
  
  m_renderTexture.generate();
}
 
void CustomEffect::resize(const U32 width, const U32 height)
{ 
  m_output.color.bind();
    m_output.color.resize( width, height, GL_RGBA8);
  m_output.color.unbind();

  m_renderTexture.bind();
    AER_CHECK( m_renderTexture.setup( &m_output.color ) );
  m_renderTexture.unbind();
  
  m_renderTexture.resize( width, height);  //
} 

void CustomEffect::apply()
{ 
  if (getTarget() == TEXTURE) { m_renderTexture.begin(); }
  
  m_input.pColor->bind( 0u );
  
  m_program.bind();
    m_program.setUniform( "uInputTex", 0);
    m_program.setUniform( "uTime", *m_input.pTime);
    ScreenQuad::Draw();
  m_program.unbind();
  
  Texture::Unbind( Texture::TEXTURE_2D, 0u);

  if (getTarget() == TEXTURE) { m_renderTexture.end(); }
}
  
} // aer
